package org.u2ml.app.domain;

import java.util.ArrayList;
import java.util.Collection;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;

import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamAsAttribute;

@Entity
@XStreamAlias("class")
public class ProjectClass extends ResponseData {

	@XStreamAsAttribute
	private Long oid;
	
	@XStreamAsAttribute
	private String name;
	
	@XStreamAsAttribute
	private Boolean userClass;
	
	@XStreamAsAttribute
	private Boolean abstractClass;
	
	@XStreamAsAttribute
	private Boolean interfaceClass;
	
	@XStreamAsAttribute
	private Boolean enumClass;
	
	@XStreamAsAttribute
	private Long projectId;

	transient private Project project;
	
	private Collection<Oid> parents;
	
	private Collection<Attribute> attributes;

	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	public Long getOid() {
		return oid;
	}
	public void setOid(Long oid) {
		this.oid = oid;
	}
	
	public void setName(String name) {
		this.name = name;
	}
	public String getName() {
		return name;
	}
	public void setUserClass(Boolean isUserClass) {
		this.userClass = isUserClass;
	}
	public Boolean isUserClass() {
		return userClass;
	}

	public void setInterfaceClass(Boolean isInterface) {
		this.interfaceClass = isInterface;
	}

	public Boolean isInterfaceClass() {
		return interfaceClass;
	}
	
	public void setAbstractClass(Boolean isAbstractClass) {
		this.abstractClass = isAbstractClass;
	}
	
	public Boolean isAbstractClass() {
		return abstractClass;
	}
	
	public void setEnumClass(Boolean isEnum) {
		this.enumClass = isEnum;
	}
	
	public Boolean isEnumClass() {
		return enumClass;
	}
	
	@ManyToOne
	@JoinColumn(name="project_id")
	public Project getProject() {
		return project;
	}
	public void setProject(Project project) {
		this.project = project;
		if (project!=null)
			this.projectId = project.getOid();
	}
	
	public void setProjectId(Long projectId) {
		this.projectId = projectId;
	}
	public Long getProjectId() {
		return projectId;
	}
	
	@ManyToMany(cascade={CascadeType.PERSIST,CascadeType.MERGE})
	@JoinTable(	name="parents",
				joinColumns={@JoinColumn(name="parent_id")},
				inverseJoinColumns={@JoinColumn(name="child_id")})
	public Collection<Oid> getParents() {
		if (parents != null)
			parents.size();
		return parents;
	}
	
	public void setParents(Collection<Oid> parents) {
		this.parents = parents;
	}
	
	public void addParent(Oid c) {
		parents.add(c);
	}
	
	public void removeParent(Oid c) {
		parents.remove(c);
	}
	
	public boolean isChildOf(Oid c) {
		if(parents != null)
			return parents.contains(c);
		else return false;
	}
	
	@OneToMany(mappedBy="parent",cascade={CascadeType.PERSIST})
	public Collection<Attribute> getAttributes() {
		if(attributes != null) {
			attributes.size();
		}
		return attributes;
	}
	public void setAttributes(Collection<Attribute> attributes) {
		this.attributes = attributes;
	}
	
	public boolean hasAttribute(Attribute attribute) {
		if(this.attributes != null) {
			return this.attributes.contains(attribute);
		}
		return false;
	}
	
	public void addAttribute(Attribute attribute) {
		if(this.attributes == null) {
			this.attributes = new ArrayList<Attribute>();
		}
		this.attributes.add(attribute);
	}
	
	public void removeAttribute(Attribute attribute) {
		this.attributes.remove(attribute);
	}
}
